package com.njtoyo.taxi.admin.rest.controller.business;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.date.DatePattern;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.io.IoUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.poi.excel.ExcelUtil;
import cn.hutool.poi.excel.ExcelWriter;
import cn.hutool.poi.excel.StyleSet;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.njtoyo.taxi.admin.aop.PassToken;
import com.njtoyo.taxi.admin.aop.PermissionScope;
import com.njtoyo.taxi.admin.mapper.master.enums.SimpleCallRideCancellationTriggerBy;
import com.njtoyo.taxi.admin.mapper.master.enums.SimpleCallRideCategory;
import com.njtoyo.taxi.admin.mapper.secondary.entity.RefundWrapper;
import com.njtoyo.taxi.admin.rest.presenter.business.ride.RideDetailPresenter;
import com.njtoyo.taxi.admin.rest.presenter.business.ride.RideListPresenter;
import com.njtoyo.taxi.admin.rest.presenter.business.ride.RideTrackPresenter;
import com.njtoyo.taxi.admin.rest.presenter.business.ride.SimpleRideDetailPresenter;
import com.njtoyo.taxi.admin.rest.presenter.business.ride.scan_ride.ScanRideListPresenter;
import com.njtoyo.taxi.admin.rest.presenter.business.simple_call_ride.ListPresenter;
import com.njtoyo.taxi.admin.rest.presenter.business.simple_call_ride.SimpleCallRideVO;
import com.njtoyo.taxi.admin.rest.wrapper.business.ride.ScanRideWrapper;
import com.njtoyo.taxi.admin.rest.wrapper.business.simpleCallRide.SimpleCallRideQueryWrapper;
import com.njtoyo.taxi.admin.service.business.SimpleCallRideService;
import com.taxi.entity.common.RestResult;
import com.njtoyo.taxi.entity.backend.AdminUser;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.apache.poi.ss.usermodel.CellStyle;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import springfox.documentation.annotations.ApiIgnore;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import javax.validation.Valid;
import java.io.IOException;
import java.util.*;

@RestController
@Api(value = "电召、一键叫车行程", tags = "电召、一键叫车行程")
@RequestMapping("business/simple_call/ride")
public class SimpleCallRideController {

    @Autowired
    private SimpleCallRideService simpleCallRideService;

    @GetMapping()
    @ApiOperation(value = "电召行程列表", notes = "权限：simple_call_ride")
    @PermissionScope(names = {"simple_call_ride"})
    RestResult<IPage<SimpleCallRideVO>> getPhoneCallRideList(@ModelAttribute("admin") AdminUser adminUser, SimpleCallRideQueryWrapper wrapper) {
        if (ObjectUtil.isNull(wrapper.getCategory())) {
            wrapper.setCategoryList(Arrays.asList(SimpleCallRideCategory.phone, SimpleCallRideCategory.phone_appointment));
        }
        return simpleCallRideService.getSimpleCallPhoneRideList(adminUser, wrapper);
    }

    @GetMapping("/list_one")
    @ApiOperation(value = "电召行程列表", notes = "权限：simple_call_ride")
    @PermissionScope(names = {"simple_call_ride"})
    RestResult<IPage<ListPresenter>> list_one(@ModelAttribute("admin") AdminUser adminUser, SimpleCallRideQueryWrapper wrapper) {
        wrapper.setCategory(SimpleCallRideCategory.phone);
        return simpleCallRideService.getList(adminUser, wrapper);
    }

    @GetMapping("/list")
    @PassToken
    @ApiOperation(value = "电召行程列表", notes = "权限：simple_call_ride")
    @PermissionScope(names = {"simple_call_ride"})
    RestResult<IPage<RideListPresenter>> list(@ModelAttribute("admin") AdminUser adminUser, SimpleCallRideQueryWrapper wrapper) {
        wrapper.setCategory(SimpleCallRideCategory.phone);
        return simpleCallRideService.getPageList(adminUser, wrapper);
    }


    @GetMapping("/{id}")
    @ApiOperation(value = "行程详情", notes = "权限：simple_call_ride_detail")
    @PermissionScope(names = {"simple_call_ride_detail"})
    RestResult<SimpleRideDetailPresenter> getDetail(@PathVariable("id") Long id) {
        return simpleCallRideService.detail(id);
    }

    @PatchMapping("/{id}/cancel")
    @ApiOperation(value = "取消行程", notes = "权限：simple_call_ride_cancel")
    @PermissionScope(names = {"simple_call_ride_cancel"})
    RestResult cancel(@ModelAttribute("admin") AdminUser adminUser, @PathVariable("id") Long id) {
        return simpleCallRideService.cancel(adminUser, id);
    }


    @PatchMapping("/{id}/cancelBy/{triggerBy}")
    RestResult cancelBy(@PathVariable("id") Long id, @PathVariable("triggerBy") String triggerBy) {
        return simpleCallRideService.cancelBy(id, triggerBy);
    }

    @PatchMapping("/{id}/start")
    @ApiOperation(value = "开始行程", notes = "开始行程即滑动乘客已上车，权限：simple_call_ride_start")
    @PermissionScope(names = {"simple_call_ride_start"})
    RestResult start(@ModelAttribute("admin") AdminUser adminUser, @PathVariable("id") Long id) {
        return simpleCallRideService.start(adminUser, id);
    }

    @GetMapping("simple")
    @ApiOperation(value = "一键叫车行程列表", notes = "权限：simple_call_ride_list")
    @PermissionScope(names = {"simple_call_ride_list"})
    RestResult<IPage<SimpleCallRideVO>> getSimpleCallRideList(@ModelAttribute("admin") AdminUser adminUser, SimpleCallRideQueryWrapper wrapper) {
        if (ObjectUtil.isNull(wrapper.getCategory())) {
            ArrayList<SimpleCallRideCategory> categories = new ArrayList<>();
            categories.add(SimpleCallRideCategory.simple);
            categories.add(SimpleCallRideCategory.my_nanjing_simple);
            wrapper.setCategoryList(categories);
        }
//        return simpleCallRideService.getList(adminUser, wrapper);
        return simpleCallRideService.getSimpleCallPhoneRideList(adminUser, wrapper);
    }


    @GetMapping("/export_simple")
    @ApiOperation(value = "导出")
    void export(@ApiIgnore @ModelAttribute("admin") AdminUser adminUser, SimpleCallRideQueryWrapper wrapper, HttpServletResponse response) throws IOException {
        if (ObjectUtil.isNull(wrapper.getCategory())) {
            ArrayList<SimpleCallRideCategory> categories = new ArrayList<>();
            categories.add(SimpleCallRideCategory.simple);
            categories.add(SimpleCallRideCategory.my_nanjing_simple);
            wrapper.setCategoryList(categories);
        }
        wrapper.setSize(100000);
        RestResult<IPage<SimpleCallRideVO>> result = simpleCallRideService.getSimpleCallPhoneRideList(adminUser, wrapper);
        IPage<SimpleCallRideVO> page = result.getData();
        List<Map<String, Object>> rows = new ArrayList<>();
        if (CollUtil.isNotEmpty(page.getRecords())) {
            for (SimpleCallRideVO ride : page.getRecords()) {
                Map<String, Object> row = new HashMap<>();
                row.put("订单号", ride.getId());
                row.put("司机编号", ride.getDriverId());
                row.put("司机名称", ride.getDriverName());
                row.put("司机电话", ride.getDriverMobileNumber());
                row.put("车牌号", ride.getTaxiPlateNumber());
                row.put("乘客编号", ride.getCustomerId());
                row.put("乘客名称", ride.getCustomerName());
                row.put("乘客电话", ride.getCustomerMobileNumber());
                row.put("下单时间", ObjectUtil.isNotNull(ride.getCreatedAt()) ? DateUtil.format(ride.getCreatedAt(), DatePattern.NORM_DATETIME_PATTERN) : "");
                row.put("行政区", ride.getAreaName());
                row.put("预约上下车信息", "起点:" + ride.getOriginName() + "\n终点:" + ride.getDestinationName());
                row.put("实际上下车信息", "起点:" + ride.getRealOriginName() + "\n终点:" + ride.getRealDestinationName());
                row.put("支付信息", "金额:" + (ObjectUtil.isNull(ride.getAmount()) ? "-" : ride.getAmount()) + "\n " +
                        "支付方式:" + (ObjectUtil.isNull(ride.getPaymentChannel()) ? "-" : ride.getPaymentChannel().getDesc()) + "\n" +
                        "支付结果:" + (ObjectUtil.isNull(ride.getPaymentChannel()) ? "-" : "已付款"));
                row.put("支付金额", ObjectUtil.isNotNull(ride.getAmount()) ? ride.getAmount() : "");
                row.put("订单状态", getStateTxt(ride));
                rows.add(row);
            }
        } else {
            Map<String, Object> row = new HashMap<>();
            row.put("订单号", "");
            row.put("司机编号", "");
            row.put("司机名称", "");
            row.put("司机电话", "");
            row.put("车牌号", "");
            row.put("乘客编号", "");
            row.put("乘客名称", "");
            row.put("乘客电话", "");
            row.put("下单时间", "");
            row.put("行政区", "");
            row.put("预约上下车信息", "");
            row.put("实际上下车信息", "");
            row.put("支付信息", "");
            row.put("订单状态", "");
            rows.add(row);
        }
        ExcelWriter writer = ExcelUtil.getWriter();
        StyleSet style = writer.getStyleSet();
        CellStyle cellStyle = style.getHeadCellStyle();
        cellStyle.setWrapText(true);
        writer.write(rows, true);
        response.setContentType("application/vnd.ms-excel;charset=utf-8");
        response.setHeader("Content-Disposition", "attachment;filename=ride_order.xls");
        ServletOutputStream out = response.getOutputStream();

        writer.flush(out, true);
        writer.close();
        IoUtil.close(out);
    }

    private String getStateTxt(SimpleCallRideVO ride) {
        String state = "";
        if (ride.getIsCancel()) {
            if (ride.getTriggerBy() == SimpleCallRideCancellationTriggerBy.driver) {
                state = "司机取消";
            } else if (ride.getTriggerBy() == SimpleCallRideCancellationTriggerBy.admin) {
                state = "系统管理员取消";
            } else if (ride.getTriggerBy() == SimpleCallRideCancellationTriggerBy.customer) {
                state = "乘客取消";
            }
        } else {
            if (ObjectUtil.isNotNull(ride.getPaymentChannel())) {
                state = "已付款";
            }
        }
        return state;
    }


    @GetMapping("/export")
    @ApiOperation(value = "电召行程-导出", notes = "电召行程-导出, 权限：simple_call_ride")
    @PermissionScope(names = {"simple_call_ride"})
    RestResult rideListExport(@ApiIgnore @ModelAttribute("admin") AdminUser adminUser, @Valid SimpleCallRideQueryWrapper wrapper, HttpServletResponse response) throws IOException {
        return simpleCallRideService.rideListExport(adminUser, wrapper, response);
    }

    @PatchMapping("/{id}/order/online-order-set-offline")
    @ApiOperation(value = "修改支付方式(改现金支付)", notes = "权限：simple_call_ride_order_set_offline")
    @PermissionScope(names = {"simple_call_ride_order_set_offline"})
    RestResult<Boolean> onlineOrderSetOffline(@PathVariable("id") Long id) {
        return simpleCallRideService.onlineOrderSetOffline(id);
    }


    @GetMapping("/{id}/track")
    @ApiOperation(value = "行程轨迹", notes = "权限：ride_track_log")
    @PermissionScope(names = {"ride_track_log"})
    RestResult<RideTrackPresenter> getTrack(@PathVariable("id") Long id) {
        return simpleCallRideService.getTrack(id);
    }


    @GetMapping("/getCountMsg")
    RestResult getCountMsg(@ModelAttribute("admin") AdminUser adminUser, SimpleCallRideQueryWrapper wrapper) {
        wrapper.setCategory(SimpleCallRideCategory.phone_appointment);
        return simpleCallRideService.getCountMsg(adminUser, wrapper);
    }



    @PostMapping("/{rideId}/order/refund")
    @PassToken
    public RestResult refundOrder(@PathVariable("rideId") Long rideId) {
        return simpleCallRideService.refundOrder(rideId);
    }

}
